﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using Newtonsoft.Json;

using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Threading;

namespace FormMainSSID
{

    public partial class Form1 : Form
    {
        
        public string path_raw = null;
        public string path_config = null;
        
        public string[] files = new string[] { };

        public Image<Gray, byte> snp = null;

        public Layer layer;
        DisplayLayer displaylayer = null;

        FormConfigEstablishDisplay form2 = null;

        bool isselect;

        move_data data;
        int[] mouse_down = new int[2];
        int[] mouse_up = new int[2];
        
        
        public Form1()
        {
            InitializeComponent();
            //this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
            imageBoxLeft.MouseWheel += new MouseEventHandler(imageBoxLeft_MouseWheel); //订阅鼠标滚轮事件
            
                    
        }


        private void imageBoxLeft_MouseWheel(object sender, MouseEventArgs e)
        {
            if (displaylayer != null)
            {
                
                data = displaylayer.MouseWheel(sender, e, imageBoxLeft.Size, this.Size);
                imageBoxLeft.Height = data.x;
                imageBoxLeft.Location = new Point(imageBoxLeft.Location.X, data.y);
                imageBoxLeft.Image = data.img;
            }
        }

        private void imageBoxLeft_MouseDown(object sender, MouseEventArgs e)
        {
            isselect = true;
            data.x = e.X;
            data.y = e.Y;
            //if (layer_0.shift)
            //{
            //    mouse_down[0] = e.X;
            //    mouse_down[1] = e.Y;
            //}
        }

        private void imageBoxLeft_MouseMove(object sender, MouseEventArgs e)
        {
            if (isselect)
            {
                if (displaylayer != null)
                {
                    data = displaylayer.MouseMove(sender, e, imageBoxLeft.Size, data);
                    imageBoxLeft.Image = data.img;
                }
            }
        }

        private void imageBoxLeft_MouseUp(object sender, MouseEventArgs e)
        {
            isselect = false;
            //Console.WriteLine(layer_0.shift);
            //Console.WriteLine(layer_0.shift_sub);
            //if (layer_0.shift && layer_0.shift_sub)
            //{
            //    Console.WriteLine("jinlaile");
            //    mouse_up[0] = e.X;
            //    mouse_up[1] = e.Y;
            //    imageBoxLeft.Image = layer_0.another(mouse_down, mouse_up);
            //}
        }

        private void establishEToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string[] name = null;
            int i;
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if(fbd.ShowDialog() == DialogResult.OK)
            {
                path_raw = fbd.SelectedPath;
                files = Directory.GetFiles(fbd.SelectedPath);
                for(i = 0; i < files.Length; i++)
                {
                    name = files[i].Split('.');
                    if(String.Compare(name[name.Length - 1], "tif") != 0)
                    {
                        break;
                    }
                }
                if (i < files.Length)
                {
                    MessageBox.Show("目录下有非tif格式的文件", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    Array.Sort(files, delegate (string s1, string s2)
                        {
                            return
                            ((int.Parse(s1.Split('_')[1]) * 10000 + int.Parse(s1.Split('_')[2]) * 100 + int.Parse(s1.Split('_')[3])).
                            CompareTo((int.Parse(s2.Split('_')[1]) * 10000 + int.Parse(s2.Split('_')[2]) * 100 + int.Parse(s2.Split('_')[3])))
                            );
                        });
                    Console.WriteLine(files[0]);
                    form2 = new FormConfigEstablishDisplay();
                    form2.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.form2_closed);
                    form2.FormMainSSID = this;
                    form2.ShowDialog();
                }
                
            }
        }

        private void configPathCToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog file = new OpenFileDialog();
            if(file.ShowDialog() == DialogResult.OK)
            {
                form2 = new FormConfigEstablishDisplay();
                form2.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.form2_closed);
                path_config = file.FileName;
                form2.FormMainSSID = this;
                form2.Show();
            }
        }
        
        private void form2_closed(object sender, FormClosedEventArgs e)
        {
            //scale_img = (float)snp_256.Height / snp_256.Width;
            imageBoxLeft.Height = (int)(imageBoxLeft.Width * ((float)snp.Height / snp.Width));
            imageBoxLeft.Location = new Point(0, (this.Height - imageBoxLeft.Height) / 2);
            imageBoxLeft.Image = snp;
            displaylayer = new DisplayLayer(layer, snp);
        }
        string offset_path = "F:\\users\\sungd\\result\\Jelly.aif.json";
        private void Form1_Load(object sender, EventArgs e)
        {
            float scale_win, scale_img;
            //offset = JsonConvert.DeserializeObject<Offset>(File.ReadAllText(offset_path));
            //Position = JsonConvert.DeserializeObject<List<List<int[]>>>(File.ReadAllText("F:\\users\\sungd\\result\\location.aif.json"));
            ////DirectoryInfo root = new DirectoryInfo(off.folder_path);
            ////FileInfo[] files = root.GetFiles();
            //files = Directory.GetFiles(offset.folder_path);
            //files_256 = Directory.GetFiles(path_256);
            //files_512 = Directory.GetFiles(path_512);
            //files_1024 = Directory.GetFiles(path_1024);
            //Array.Sort(files, delegate (string s1, string s2)
            //    {
            //        return
            //        ((int.Parse(s1.Split('_')[1]) * 10000 + int.Parse(s1.Split('_')[2]) * 100 + int.Parse(s1.Split('_')[3])).
            //        CompareTo((int.Parse(s2.Split('_')[1]) * 10000 + int.Parse(s2.Split('_')[2]) * 100 + int.Parse(s2.Split('_')[3])))
            //        );
            //    });
            //Array.Sort(files_256, delegate (string s1, string s2)
            //{
            //    return
            //    ((int.Parse(s1.Split('_')[2]) * 10000 + int.Parse(s1.Split('_')[3]) * 100 + int.Parse(s1.Split('_')[4])).
            //    CompareTo((int.Parse(s2.Split('_')[2]) * 10000 + int.Parse(s2.Split('_')[3]) * 100 + int.Parse(s2.Split('_')[4])))
            //    );
            //});
            //Array.Sort(files_512, delegate (string s1, string s2)
            //{
            //    return
            //    ((int.Parse(s1.Split('_')[2]) * 10000 + int.Parse(s1.Split('_')[3]) * 100 + int.Parse(s1.Split('_')[4])).
            //    CompareTo((int.Parse(s2.Split('_')[2]) * 10000 + int.Parse(s2.Split('_')[3]) * 100 + int.Parse(s2.Split('_')[4])))
            //    );
            //});
            //Array.Sort(files_1024, delegate (string s1, string s2)
            //{
            //    return
            //    ((int.Parse(s1.Split('_')[2]) * 10000 + int.Parse(s1.Split('_')[3]) * 100 + int.Parse(s1.Split('_')[4])).
            //    CompareTo((int.Parse(s2.Split('_')[2]) * 10000 + int.Parse(s2.Split('_')[3]) * 100 + int.Parse(s2.Split('_')[4])))
            //    );
            //});
            ////Console.WriteLine(/*int.Parse*/(files[0].Split('_')[0].Split('\\')[-1]));
            ////for (int i = 0; i < 100; i++)
            ////{
            ////    Console.WriteLine(files[i]);
            ////}
            ////Mat img = new Mat(files[0], ImreadModes.AnyColor);
            //////Console.WriteLine(img.Size);
            ////Mat snp = new Mat(256*(offset.size_Layer[0]+1), 256*(offset.size_Layer[1]+1), DepthType.Cv16S, img.NumberOfChannels);
            ////image = img.Resize(image.Size.Width, image.Size.Height, Emgu.CV.CvEnum.Inter.Cubic);
            ////Rectangle rect = new Rectangle(128, 128, img.Width, img.Height);


            ////Image<Gray, byte> img = new Image<Gray, byte>(files[0]);
            ////Image<Gray, byte> image = new Image<Gray, byte>(256, 256);
            ////Image<Gray, byte> snp = new Image<Gray, byte>(256 * (offset.size_Layer[1] + 1), 256 * (offset.size_Layer[0] + 1));
            ////Console.WriteLine(snp.Size);
            ////image = img.Resize(256, 256, Emgu.CV.CvEnum.Inter.Cubic);
            ////Rectangle rect = new Rectangle(128, 128, 256, 256);


            ////CvInvoke.cvCopy(snp, image, IntPtr.Zero);
            ////for (int i = 0; i < 256; i++)
            ////    for (int j = 0; j < 256; j++)
            ////    {
            ////        snp[128 + i, 128 + j] = image[i, j];
            ////    }
            ////copy(128, 128, snp, image);


            //snp_256 = new Image<Gray, byte>(@"C:\Users\user\Documents\result\resn1.jpg");
            //wid = snp_256.Width;
            //hei = snp_256.Height;
            ////Console.WriteLine(offset.folder_path);
            ////Console.WriteLine(files[0]);
            ////Mat snp = new Mat(256*(offset.size_Layer[0]+1),256*(offset.size_Layer[1]+1), DepthType.Default, 1);
            //rect_256 = new Rectangle(0, 0, snp_256.Width, snp_256.Height);
            //scale_img = (float)snp_256.Height / snp_256.Width;
            //scale_win = (float)imageBoxLeft.Height / imageBoxLeft.Width;
            //imageBoxLeft.Height = (int)(imageBoxLeft.Width * scale_img);
            //imageBoxLeft.Location = new Point(0, (this.Height - imageBoxLeft.Height) / 2);
            ////snp_512 = new Image<Gray, byte>(@"D:\Documents\result\resn122.jpg");
            //xr = 0;
            //yr = 0;
            //widr = snp_256.Width;
            //heir = snp_256.Height;
            //imageBoxLeft.Image = snp_256.GetSubRect(rect_256);
            ////puzzle(256);
            //image = new Image<Gray, byte>(files[0]);
            //bei = image.Width / 256;
            ////Joint joint = new Joint(this);
            //layer_1 = new Layer(this, snp_256, path_256, offset, Position, 1, false);
            //layer_2 = new Layer(this, snp_256, path_512, offset, Position, 2, false);
            //layer_3 = new Layer(this, snp_256, path_1024, offset, Position, 3, true);
            //layer_0 = new Layer(this, snp_256, offset.folder_path, offset, Position, 0, false);
            //layer_1.ShiftEvent += new ShiftEventHandler(layer_2.ReceiveEvent);
            //layer_2.OverPuzzleEvent += new OverPuzzleEventHandler(layer_1.ReceiveOverPuzzle);
            //layer_1.SendRectEvent += new SendRectEventHandler(layer_2.Draw_rect);
            //layer_2.OverSelfEvent += new OverSelfEventHandler(layer_1.ReceiverOverSelf);
            //layer_1.OverBackEvent += new OverBackEventHandler(layer_2.ReceiveBeforeOverSelf);
            //layer_2.StartBeforeOverSelfEvent += new StartBeforeOverSelfEventHandler(layer_1.ReceiveBackStartSelf);

            //layer_2.ShiftEvent += new ShiftEventHandler(layer_3.ReceiveEvent);
            //layer_3.OverPuzzleEvent += new OverPuzzleEventHandler(layer_2.ReceiveOverPuzzle);
            //layer_2.SendRectEvent += new SendRectEventHandler(layer_3.Draw_rect);
            //layer_3.OverSelfEvent += new OverSelfEventHandler(layer_2.ReceiverOverSelf);
            //layer_2.OverBackEvent += new OverBackEventHandler(layer_3.ReceiveBeforeOverSelf);
            //layer_3.StartBeforeOverSelfEvent += new StartBeforeOverSelfEventHandler(layer_2.ReceiveBackStartSelf);

            //layer_3.ShiftEvent += new ShiftEventHandler(layer_0.ReceiveEvent);
            //layer_0.OverPuzzleEvent += new OverPuzzleEventHandler(layer_3.ReceiveOverPuzzle);
            //layer_3.SendRectEvent += new SendRectEventHandler(layer_0.Draw_rect);
            //layer_0.OverSelfEvent += new OverSelfEventHandler(layer_3.ReceiverOverSelf);
            //layer_3.OverBackEvent += new OverBackEventHandler(layer_0.ReceiveBeforeOverSelf);
            //layer_0.StartBeforeOverSelfEvent += new StartBeforeOverSelfEventHandler(layer_3.ReceiveBackStartSelf);


            //Image<Gray, byte> snp;
            //for (int i = 0; i < offset.size_Layer[0]; i++)
            //{
            //    for (int j = 0; j < offset.size_Layer[1]; j++)
            //    {
            //        snp = new Image<Gray, byte>(files[i * offset.size_Layer[1] + j + 154]);
            //        snp_256 = snp.Resize(256, 256, Inter.Cubic);
            //        snp_256.Save(@"C:\Users\user\Documents\snp_256\" + files[i * offset.size_Layer[1] + j].Split('\\')[5]);
            //        snp_512 = snp.Resize(512, 512, Inter.Cubic);
            //        snp_512.Save(@"C:\Users\user\Documents\snp_512\" + files[i * offset.size_Layer[1] + j].Split('\\')[5]);
            //        snp_512 = snp.Resize(1024, 1024, Inter.Cubic);
            //        snp_512.Save(@"C:\Users\user\Documents\snp_1024\" + files[i * offset.size_Layer[1] + j].Split('\\')[5]);
            //    }
            //}

            //List<int[]> array = new List<int[]>();
            //ThreadPool.QueueUserWorkItem(puzzle, 256);

            //puzzle(256, offset.folder_path);
            //for (int i = 0; i < offset.size_Layer[0]; i++)
            //{
            //    for (int j = 0; j < offset.size_Layer[1]; j++)
            //    {
            //        Spot[0] = i;
            //        Spot[1] = j;
            //        array.Add((int[])Spot.Clone());
            //    }
            //    Position.Add(new List<int[]>(array.ToArray()));

            //    array.Clear();
            //}
            //File.WriteAllText("C:\\Users\\user\\Documents\\result\\Jellylocation.aif.json", JsonConvert.SerializeObject(Position));

        }
        public void copy(int hang, int lie, Image<Gray, byte> snp, Image<Gray, byte> img)
        {
            for (int i = 0; i < img.Height; i++)
                for (int j = 0; j < img.Width; j++)
                {
                    snp[hang + i, lie + j] = img[i, j];
                }
        }

        //private void puzzle(object siz)
        //{
        //    int size;
        //    size = int.Parse(siz.ToString());
        //    int[] offset2to1 = new int[2];
        //    int offtrainx = size / 2;
        //    int offqueryx = size / 2;
        //    int offtrainy = size / 2;
        //    int offqueryy = size / 2;

        //    int max_xz = 0, max_xf = 0, max_x = 0;
        //    int max_yz = 0, max_yf = 0, max_y = 0;
        //    int sum = 0;

        //    int init_x = 0, init_y = 0;

        //    List<int[]> array = new List<int[]>();

        //    //var files = Directory.GetFiles(offset.folder_path);
        //    Image<Gray, byte> img = new Image<Gray, byte>(files[0]);

        //    for (int i = 0; i < offset.size_Layer[1] - 1; i++)
        //    {
        //        offset2to1[1] = (int)(size * ((double)offset.l2rindex_array_map[0, 0, i, 1] / img.Height));
        //        sum += offset2to1[1];
        //        if (sum >= 0)
        //        {
        //            if (sum > max_xz)
        //            {
        //                max_xz = sum;
        //            }
        //        }
        //        else
        //        {
        //            if (sum < max_xf)
        //            {
        //                max_xf = sum;
        //            }
        //        }
        //    }
        //    max_x = max_xz - max_xf;

        //    for (int i = 0; i < offset.size_Layer[0] - 1; i++)
        //    {
        //        offset2to1[0] = (int)(size * ((double)offset.u2dindex_array_map[0, 0, i, 0] / img.Width));
        //        sum += offset2to1[0];
        //        if (sum >= 0)
        //        {
        //            if (sum > max_yz)
        //            {
        //                max_yz = sum;
        //            }
        //        }
        //        else
        //        {
        //            if (sum < max_yf)
        //            {
        //                max_yf = sum;
        //            }
        //        }
        //    }
        //    max_y = max_yz - max_yf;


        //    Image<Gray, byte> snp = new Image<Gray, byte>(size * (offset.size_Layer[1] + 1) + max_y, size * (offset.size_Layer[0] + 1) + max_x);
        //    Image<Gray, byte> ex1 = new Image<Gray, byte>(img.Width, img.Height);

        //    for (int h = 0; h < offset.size_Layer[0]; h++)
        //    {
        //        ex1 = new Image<Gray, byte>(files_256[h * offset.size_Layer[1]]);
        //        //ex1 = ex1.Resize(size, size, Emgu.CV.CvEnum.Inter.Cubic);
        //        if (h == 0)
        //        {
        //            init_x = (size / 2) - max_yf;
        //            init_y = (size / 2) - max_xf;
        //            copy(init_y, init_x, snp, ex1);
        //        }
        //        else
        //        {
        //            offset2to1[0] = (int)(size * ((double)offset.u2dindex_array_map[0, 0, h - 1, 0] / img.Width));
        //            offset2to1[1] = (int)(size * ((double)offset.u2dindex_array_map[0, 0, h - 1, 1] / img.Height));
        //            if (offset2to1[0] >= 0)
        //            {
        //                init_x = offset2to1[0] + init_x;
        //            }
        //            else
        //            {
        //                init_x = offset2to1[0] + init_x;
        //            }
        //            if (offset2to1[1] >= 0)
        //            {
        //                init_y = offset2to1[1] + init_y;
        //            }
        //            else
        //            {
        //                offqueryy = -offset2to1[1];
        //                offtrainy = 0;
        //            }
        //            copy(init_y, init_x, snp, ex1);
        //        }
        //        Spot[0] = init_x;
        //        Spot[1] = init_y;
        //        array.Add((int[])Spot.Clone());
        //        offtrainy = init_y;
        //        offtrainx = init_x;
        //        for (int i = 0; i < offset.size_Layer[1] - 1; i++)
        //        {
        //            ex1 = new Image<Gray, byte>(files_256[h * offset.size_Layer[1] + i + 1]);
        //            //ex1 = ex1.Resize(size, size, Emgu.CV.CvEnum.Inter.Cubic);
        //            offset2to1[0] = (int)(size * ((double)offset.l2rindex_array_map[0, h, i, 0] / img.Height));
        //            offset2to1[1] = (int)(size * ((double)offset.l2rindex_array_map[0, h, i, 1] / img.Width));
        //            if (offset2to1[0] >= 0)
        //            {
        //                offtrainx = offset2to1[0] + offtrainx;
        //            }
        //            else
        //            {
        //                offqueryx = -offset2to1[0];
        //                offtrainx = 0;
        //            }
        //            if (offset2to1[1] >= 0)
        //            {
        //                offtrainy = offset2to1[1] + offtrainy;
        //            }
        //            else
        //            {
        //                offtrainy = offset2to1[1] + offtrainy;
        //            }

        //            copy(offtrainy, offtrainx, snp, ex1);
        //            Spot[0] = offtrainx;
        //            Spot[1] = offtrainy;
        //            array.Add((int[])Spot.Clone());
        //            //Console.WriteLine(offset.size_Layer[1]);
        //            //Console.WriteLine(offtrainx);
        //            Console.WriteLine(h.ToString() + ",," + i.ToString());
        //        }
        //        Position.Add(new List<int[]>(array.ToArray()));
        //        array.Clear();

        //    }
        //    snp.Save(@"C:\Users\user\Documents\result\snp1.jpg");
        //    File.WriteAllText("C:\\Users\\user\\Documents\\result\\Jelly2location.aif.json", JsonConvert.SerializeObject(Position));
        //    //Console.WriteLine(snp[1000, 4000]);
        //    //Console.WriteLine(offset2to1[1]);
        //    //imageBoxLeft.Image = snp;
        //}

        //public int[] Scan(int X, int Y, int who = 0)
        //{
        //    int[] spot = new int[2] { 0, 0 };
        //    int x, y;
        //    if (who == 0)
        //    {
        //        x = (X * rect_256.Width / imageBoxLeft.Width) + rect_256.X;
        //        y = (Y * rect_256.Height / imageBoxLeft.Height) + rect_256.Y;
        //    }
        //    else
        //    {
        //        x = X;
        //        y = Y;
        //    }
        //    for (int i = 0; i < Position.Count; i++)
        //    {
        //        for (int j = 0; j < Position[i].Count; j++)
        //        {
        //            if (i == 0 && j == 0 && ((x >= Position[i][j][0] && x < Position[i][j + 1][0] && y < Position[i][j][1]) || (x <= Position[i][j][0] && y >= Position[i][j][1] && y < Position[i + 1][j][1]) || (x <= Position[i][j][0] && y < Position[i][j][1])))
        //            {
        //                spot[0] = i;
        //                spot[1] = j;
        //                break;
        //            }
        //            else if (i == 0 && y < Position[i][j][1])
        //            {
        //                if ((j == Position[i].Count - 1 && x >= Position[i][j][0]) || (x >= Position[i][j][0] && x < Position[i][j + 1][0]))
        //                {
        //                    spot[0] = i;
        //                    spot[1] = j;
        //                    break;
        //                }
        //            }
        //            else if (j == 0 && x <= Position[i][j][0])
        //            {
        //                if ((i == Position.Count - 1 && y >= Position[i][j][1]) || (y >= Position[i][j][1] && y < Position[i + 1][j][1]))
        //                {
        //                    spot[0] = i;
        //                    spot[1] = j;
        //                    break;
        //                }

        //            }
        //            else if ((j == Position[i].Count - 1 && x >= Position[i][j][0]) || (x >= Position[i][j][0] && x < Position[i][j + 1][0]))
        //            {
        //                if ((i == Position.Count - 1 && y >= Position[i][j][1]) || (y >= Position[i][j][1] && y < Position[i + 1][j][1]))
        //                {
        //                    spot[0] = i;
        //                    spot[1] = j;
        //                    break;
        //                }
        //            }
        //        }
        //    }
        //    return spot;
        //}

        public double Max(int w, int wid, int h, int hei)
        {
            double x, y;
            x = Math.Round((double)(w) / wid, 2);
            y = Math.Round((double)(h) / hei, 2);
            if (y > x)
            {
                return y;
            }
            return x;
        }


    }

    public delegate void ShiftEventHandler(int[] start, int[] end);
    public delegate void OverPuzzleEventHandler();
    public delegate void SendRectEventHandler(int[] los, int[] rect_los, int rect_wid, int rect_hei, int img_size);
    public delegate void OverSelfEventHandler();
    public delegate void OverBackEventHandler();
    public delegate void StartBeforeOverSelfEventHandler();


    //public class move_data
    //{
    //    public Image<Gray, byte> img { get; set; }
    //    public int x { get; set; }
    //    public int y { get; set; }
    //};

    
    /// <summary>
    /// 
    /// </summary>
    //public class Layer
    //{
    //    /// <summary>
    //    /// 
    //    /// </summary>
    //    Form1 form;//

    //    /// <summary>
    //    /// level:放缩矩形框计算大小，与矩形框相乘
    //    /// </summary>
    //    double level = 1.0;
    //    double box_level = 1.0;
    //    double scale_snp, scale_win;
    //    double prop;

    //    public bool box = false;
    //    public bool shift = false;

    //    bool send_back = false;
    //    bool control_back = false;

    //    bool isLast = false;
    //    int size_yuan;

    //    bool rect_x_zero = false;
    //    bool rect_y_zero = false;
    //    bool rect_x_max = false;
    //    bool rect_y_max = false;

    //    bool send_sub = false;
    //    public bool shift_sub = false;
    //    Image<Gray, byte> snp_sub = null;

    //    Image<Gray, byte> snp = null;
    //    Rectangle rect = new Rectangle(0, 0, 0, 0);
    //    Rectangle rect_start = new Rectangle(0, 0, 0, 0);

    //    int widr, heir;
    //    int lay;

    //    Offset offset = null;

    //    List<List<int[]>> Position = new List<List<int[]>>();

    //    string path = null;

    //    int[] start_self = new int[2];
    //    int[] end_self = new int[2];
    //    int[] pos_self = new int[2];

    //    int[] start_before = new int[2];
    //    int[] end_before = new int[2];
    //    int[] pos_before = new int[2];

    //    int[] start_back = new int[2];
    //    int[] end_back = new int[2];
    //    int[] pos_back = new int[2];

    //    int[] start_sub = new int[2];
    //    int[] end_sub = new int[2];
    //    int[] pos_sub = new int[2];

    //    int[] rect_leftlos = new int[2];
    //    int[] rect_rightlos = new int[2];

    //    public event ShiftEventHandler ShiftEvent;
    //    public event OverPuzzleEventHandler OverPuzzleEvent;
    //    public event SendRectEventHandler SendRectEvent;
    //    public event OverSelfEventHandler OverSelfEvent;
    //    public event OverBackEventHandler OverBackEvent;
    //    public event StartBeforeOverSelfEventHandler StartBeforeOverSelfEvent;

    //    Task task = null;

    //    /// <summary>
    //    /// 
    //    /// </summary>
    //    /// <param name="form1"></param>
    //    /// <param name="snp1"></param>
    //    /// <param name="path1"></param>
    //    /// <param name="offset1"></param>
    //    /// <param name="Position1"></param>
    //    /// <param name="la"></param>
    //    /// <param name="last"></param>
    //    public Layer(Form1 form1, Image<Gray, byte> snp1, string path1, Offset offset1, List<List<int[]>> Position1, int la, bool last)
    //    {
    //        form = form1;
    //        snp = snp1;
    //        path = path1;
    //        offset = offset1;
    //        Position = Position1;
    //        lay = la;
    //        isLast = last;
    //        rect.X = 0;
    //        rect.Y = 0;
    //        rect.Width = snp.Width;
    //        rect.Height = snp.Height;
    //        scale_snp = (float)rect.Height / rect.Width;
    //        scale_win = (float)form.Height / form.Width;
    //        if (la == 1)
    //        {
    //            shift = true;
    //            start_self[0] = 0;
    //            start_self[1] = 0;
    //            pos_self[0] = Position[0][0][0];
    //            pos_self[1] = Position[0][0][1];

    //        }
    //        if (last)
    //        {
    //            string[] files = Directory.GetFiles(offset.folder_path);
    //            Image<Gray, byte> yuan = new Image<Gray, byte>(files[0]);
    //            size_yuan = yuan.Width;
    //        }
    //    }

    //    public move_data box_wheel(object sender, MouseEventArgs e)
    //    {
    //        move_data data1;
    //        int x, y, poi_y;
    //        int box_height;


    //        if (e.Delta > 0)
    //        {
    //            box_level = box_level - 0.1;
    //        }
    //        else if (e.Delta < 0)
    //        {
    //            box_level = box_level + 0.1;

    //            if (box_level > 1.0)
    //            {
    //                box_level = 1.0;
    //            }
    //        }
    //        //if (!shift_512)
    //        {
    //            x = (e.X * rect.Width / form.imageBoxLeft.Width) + rect.X - (int)(snp.Width * (box_level / 2.0));
    //            y = 0;
    //            rect.Width = (int)(snp.Width * box_level);
    //            box_height = form.imageBoxLeft.Width * rect.Height / rect.Width;
    //            //poi_y  = form.imageBoxLeft.Location.Y - ((box_height - form.imageBoxLeft.Height) / 2);
    //            poi_y = (form.Height - box_height) / 2;
    //            if (x < 0)
    //            {
    //                x = 0;
    //            }

    //            if (x + (int)(snp.Width * box_level) > snp.Width)
    //            {
    //                x = snp.Width - (int)(snp.Width * box_level);
    //            }
    //            if (box_height >= form.Height)
    //            {
    //                box_height = form.Height;
    //                rect.Height = rect.Width * box_height / form.imageBoxLeft.Width;
    //                widr = rect.Width;
    //                heir = rect.Height;
    //                scale_win = (double)rect.Height / rect.Width;
    //                box = true;
    //                Console.WriteLine(form.imageBoxLeft.Size);
    //            }
    //            if (box_level == 1.0)
    //            {
    //                rect.Height = snp.Height;
    //            }
    //        }
    //        rect.X = x;
    //        rect.Y = y;

    //        data1.x = box_height;
    //        data1.y = poi_y;
    //        //rect = new Rectangle(xr, yr, widr, heir);
    //        data1.img = snp.GetSubRect(rect);

    //        return data1;
    //    }

    //    public Image<Gray, byte> wheel(object sender, MouseEventArgs e, double prop1)
    //    {
    //        int x, y;
    //        prop = prop1;

    //        if (e.Delta > 0)
    //        {
    //            level = level - 0.1;

    //            if (level < 0.5)
    //            {
    //                if (level < 0.1)
    //                {
    //                    level = 0.1;
    //                }
    //            }
    //        }
    //        else if (e.Delta < 0)
    //        {
    //            level = level + 0.1;
    //            if (level > 1.0)
    //            {
    //                level = 1.0;
    //            }
    //        }
    //        //if (!shift_512)
    //        {
    //            x = (e.X * rect.Width / form.imageBoxLeft.Width) + rect.X - (int)(widr * (level / 2.0));
    //            if (x < 0)
    //            {
    //                x = 0;
    //            }
    //            y = (e.Y * rect.Height / form.imageBoxLeft.Height) + rect.Y - (int)(widr * level * scale_win / 2.0);
    //            if (y < 0)
    //            {
    //                y = 0;
    //            }
    //            if (x + (int)(widr * level) > snp.Width)
    //            {
    //                x = snp.Width - (int)(widr * level);
    //            }
    //            if (y + (int)(widr * level * scale_win) > snp.Height)
    //            {
    //                y = snp.Height - (int)(widr * level * scale_win);
    //            }
    //            rect.X = x;
    //            rect.Y = y;
    //            rect.Width = (int)(widr * level);
    //            rect.Height = (int)(widr * level * scale_win);
    //            if (level == 1.0)
    //            {
    //                if (lay == 1)
    //                {
    //                    box = false;
    //                }
    //            }
    //            if ((lay != 1) && level >= 0.8)
    //            {
    //                if (StartBeforeOverSelfEvent != null)
    //                {
    //                    StartBeforeOverSelfEvent();
    //                    shift = false;
    //                }
    //            }
    //            if (!isLast)
    //            {
    //                if ((rect.Width * rect.Height) <= (form.imageBoxLeft.Width * form.imageBoxLeft.Height * prop))
    //                {
    //                    if (!send_back)
    //                    {
    //                        start_back = Scan(((rect.X - pos_self[0]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][0], ((rect.Y - pos_self[1]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][1]);
    //                        end_back = Scan(((rect.X + rect.Width - pos_self[0]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][0], ((rect.Y + rect.Height - pos_self[1]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][1]);
    //                        control_back = true;
    //                        if (ShiftEvent != null)
    //                        {
    //                            send_back = true;
    //                            ShiftEvent(start_back, end_back);
    //                        }
    //                    }
    //                }
    //                else
    //                {
    //                    control_back = false;
    //                    send_back = false;
    //                    if (OverBackEvent != null)
    //                    {
    //                        OverBackEvent();
    //                    }
    //                }
    //            }
    //            else
    //            {
    //                if ((rect.Width * rect.Height) <= (form.imageBoxLeft.Width * form.imageBoxLeft.Height * prop))
    //                {
    //                    if (!send_back)
    //                    {
    //                        start_back = Scan(((rect.X + rect.Width / 2 - pos_self[0]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][0], ((rect.Y + rect.Height - pos_self[1]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][1]);
    //                        end_back[0] = start_back[0];
    //                        end_back[1] = start_back[1];
    //                        control_back = true;
    //                        if (ShiftEvent != null)
    //                        {
    //                            send_back = true;
    //                            ShiftEvent(start_back, end_back);
    //                        }
    //                    }
    //                }
    //                else
    //                {
    //                    control_back = false;
    //                    send_back = false;
    //                    if (OverBackEvent != null)
    //                    {
    //                        OverBackEvent();
    //                    }
    //                }
    //            }
    //            if (!send_back)
    //            {
    //                rect_start.X = rect.X;
    //                rect_start.Y = rect.Y;
    //                rect_start.Width = rect.Width;
    //                rect_start.Height = rect.Height;
    //            }

    //            Console.WriteLine(rect.Size);
    //            //Console.WriteLine(form.imageBoxLeft.Size);
    //            //rect = new Rectangle(xr, yr, widr, heir);
    //            return snp.GetSubRect(rect);
    //            //label1.Text = level_256.ToString();
    //            //label4.Text = "256";
    //        }
    //    }

    //    public move_data move(object sender, MouseEventArgs e, int xm, int ym)
    //    {
    //        move_data data;
    //        int x, y;

    //        if (shift_sub && lay > 1)
    //        {
    //            rect.X = ((((rect.X - pos_self[0]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][0]) - Position[start_sub[0]][start_sub[1]][0]) * (int)(Math.Pow(2, lay - 1)) + pos_sub[0];
    //            rect.Y = ((((rect.Y - pos_self[1]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][1]) - Position[start_sub[0]][start_sub[1]][1]) * (int)(Math.Pow(2, lay - 1)) + pos_sub[1];
    //            widr = snp_sub.Width;
    //            heir = snp_sub.Width * rect.Height / rect.Width;
    //            level = (double)rect.Width / widr;
    //            snp = snp_sub;
    //            start_self[0] = start_sub[0];
    //            start_self[1] = start_sub[1];
    //            end_self[0] = end_sub[0];
    //            end_self[1] = end_sub[1];
    //            pos_self[0] = pos_sub[0];
    //            pos_self[1] = pos_sub[1];
    //            shift_sub = false;
    //            send_sub = false;
    //        }
    //        if (lay == 0)
    //        {
    //            rect_x_zero = false;
    //            rect_y_zero = false;
    //            rect_x_max = false;
    //            rect_y_max = false;
    //            shift_sub = false;
    //        }

    //        x = rect.X - (int)(((e.X - xm) * snp.Width / form.imageBoxLeft.Width) * level);
    //        y = rect.Y - (int)(((e.Y - ym) * snp.Height / form.imageBoxLeft.Height) * level);

    //        if (x < 0)
    //        {
    //            x = 0;
    //            if (lay == 0 && !send_sub)
    //            {
    //                shift_sub = true;
    //                rect_x_zero = true;
    //            }
    //        }
    //        if ((x + rect.Width) > snp.Width)
    //        {
    //            x = rect.X;
    //            if (lay == 0 && !send_sub)
    //            {
    //                shift_sub = true;
    //                rect_x_max = true;
    //            }
    //        }

    //        if (y < 0)
    //        {
    //            y = 0;
    //            if (lay == 0 && !send_sub)
    //            {
    //                shift_sub = true;
    //                rect_y_zero = true;
    //            }
    //        }
    //        if ((y + rect.Height) > snp.Height)
    //        {
    //            y = rect.Y;
    //            if (lay == 0 && !send_sub)
    //            {
    //                shift_sub = true;
    //                rect_y_max = true;
    //            }
    //        }
    //        data.x = e.X;
    //        data.y = e.Y;
    //        rect.X = x;
    //        rect.Y = y;
    //        data.img = snp.GetSubRect(rect);
    //        Console.WriteLine(rect.Location);
    //        Console.WriteLine(rect.Size);
    //        if (lay > 1)
    //        {
    //            rect_leftlos = Scan(((rect.X - pos_self[0]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][0], ((rect.Y - pos_self[1]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][1]);
    //            rect_rightlos = Scan(((rect.X + rect.Width - pos_self[0]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][0], ((rect.Y + rect.Height - pos_self[1]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][1]);
    //        }
    //        //if(lay == 0 && !send_sub)
    //        //{
    //        //    if(rect.X == 0 || rect.Y == 0 || rect.X + rect.Width == snp.Width || rect.Y + rect.Height == snp.Height)
    //        //    {
    //        //        shift_sub = true;
    //        //    }
    //        //}
    //        if (lay != 1 && lay != 0)
    //        {
    //            if (!send_sub)
    //            {
    //                if (((rect_leftlos[0] <= start_self[0]) && (start_self[0] > 0)) || ((rect_leftlos[1] <= start_self[1]) && (start_self[1] > 0))
    //                    || ((rect_rightlos[0] >= end_self[0]) && (end_self[0] < (offset.size_Layer[0] - 1))) || ((rect_rightlos[1] >= end_self[1]) && (end_self[1] < (offset.size_Layer[1] - 1))))
    //                {
    //                    start_sub = Scan(((rect.X - widr / 2 - pos_self[0]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][0], ((rect.Y - heir / 2 - pos_self[1]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][1]);
    //                    end_sub = Scan(((rect.X + rect.Width / 2 + widr / 2 - pos_self[0]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][0], ((rect.Y + rect.Height / 2 + heir / 2 - pos_self[1]) / (int)(Math.Pow(2, lay - 1))) + Position[start_self[0]][start_self[1]][1]);
    //                    task =
    //                          Task.Run(
    //                          () => this.puzzle(start_sub, end_sub, true));
    //                    send_sub = true;
    //                }
    //            }
    //        }
    //        if (!isLast)
    //        {
    //            if ((rect.Width * rect.Height) <= (form.imageBoxLeft.Width * form.imageBoxLeft.Height * prop))
    //            {
    //                ;
    //            }
    //            else
    //            {
    //                control_back = false;
    //                send_back = false;
    //                if (OverBackEvent != null)
    //                {
    //                    OverBackEvent();
    //                }
    //            }
    //        }
    //        else
    //        {
    //            if ((rect.Width * rect.Height) * (size_yuan / (Math.Pow(2, lay - 1) * 256)) <= size_yuan * size_yuan * prop)
    //            {
    //                if (!send_back)
    //                {
    //                    ;
    //                }
    //            }
    //            else
    //            {
    //                control_back = false;
    //                send_back = false;
    //                if (OverBackEvent != null)
    //                {
    //                    OverBackEvent();
    //                }
    //            }
    //        }
    //        return data;
    //    }

    //    public Image<Gray, byte> another(int[] mouse_down, int[] mouse_up)
    //    {
    //        Console.WriteLine("1234");
    //        Console.WriteLine(start_self[0]);
    //        Console.WriteLine(start_self[1]);
    //        start_sub[0] = start_self[0];
    //        start_sub[1] = start_self[1];
    //        end_sub[0] = end_self[0];
    //        end_sub[1] = end_self[1];
    //        send_sub = true;
    //        //if (rect.X == 0)
    //        //{
    //        //    if (rect.Y == 0)
    //        //    {
    //        //        if (Math.Abs(mouse_up[0] - mouse_down[0]) >= Math.Abs(mouse_up[1] - mouse_down[1]))
    //        //        {
    //        //            if (start_self[1] > 0)
    //        //            {
    //        //                start_sub[1] = start_self[1] - 1;
    //        //                end_sub[1] = end_self[1] - 1;
    //        //                this.puzzle(start_sub, end_sub, true);
    //        //                snp = snp_sub;
    //        //                rect.X = snp.Width - rect.Width;
    //        //                Console.WriteLine("10");
    //        //            }
    //        //        }
    //        //        else
    //        //        {
    //        //            if (start_self[0] > 0)
    //        //            {
    //        //                start_sub[0] = start_self[0] - 1;
    //        //                end_sub[0] = end_self[0] - 1;
    //        //                this.puzzle(start_sub, end_sub, true);
    //        //                snp = snp_sub;
    //        //                rect.Y = snp.Height - rect.Height;
    //        //                Console.WriteLine("11");
    //        //            }
    //        //        }
    //        //    }
    //        //    else if (rect.Y + rect.Height == snp.Height)
    //        //    {
    //        //        if (Math.Abs(mouse_up[0] - mouse_down[0]) >= Math.Abs(mouse_up[1] - mouse_down[1]))
    //        //        {
    //        //            if (start_self[1] > 0)
    //        //            {
    //        //                start_sub[1] = start_self[1] - 1;
    //        //                end_sub[1] = end_self[1] - 1;
    //        //                this.puzzle(start_sub, end_sub, true);
    //        //                snp = snp_sub;
    //        //                rect.X = snp.Width - rect.Width;
    //        //                Console.WriteLine("12");
    //        //            }
    //        //        }
    //        //        else
    //        //        {
    //        //            if (start_self[0] < offset.size_Layer[0] - 1)
    //        //            {
    //        //                start_sub[0] = start_self[0] + 1;
    //        //                end_sub[0] = end_self[0] + 1;
    //        //                this.puzzle(start_sub, end_sub, true);
    //        //                snp = snp_sub;
    //        //                rect.Y = 0;
    //        //                Console.WriteLine("13");
    //        //            }
    //        //        }
    //        //    }
    //        //    else
    //        //    {
    //        //        if (start_self[1] > 0)
    //        //        {
    //        //            start_sub[1] = start_self[1] - 1;
    //        //            end_sub[1] = end_self[1] - 1;
    //        //            this.puzzle(start_sub, end_sub, true);
    //        //            snp = snp_sub;
    //        //            rect.X = snp.Width - rect.Width;
    //        //            Console.WriteLine("14");
    //        //        }
    //        //    }
    //        //    start_self[0] = start_sub[0];
    //        //    start_self[1] = start_sub[1];
    //        //    end_self[0] = end_sub[0];
    //        //    end_self[1] = end_sub[1];
    //        //    Console.WriteLine("1");
    //        //}

    //        //else if (rect.X + rect.Width == snp.Width)
    //        //{
    //        //    if (rect.Y == 0)
    //        //    {
    //        //        if (Math.Abs(mouse_up[0] - mouse_down[0]) >= Math.Abs(mouse_up[1] - mouse_down[1]))
    //        //        {
    //        //            if (start_self[1] < offset.size_Layer[1] - 1)
    //        //            {
    //        //                start_sub[1] = start_self[1] + 1;
    //        //                end_sub[1] = end_self[1] + 1;
    //        //                this.puzzle(start_sub, end_sub, true);
    //        //                snp = snp_sub;
    //        //                rect.X = 0;
    //        //            }
    //        //        }
    //        //        else
    //        //        {
    //        //            if (start_self[0] > 0)
    //        //            {
    //        //                start_sub[0] = start_self[0] - 1;
    //        //                end_sub[0] = end_self[0] - 1;
    //        //                this.puzzle(start_sub, end_sub, true);
    //        //                snp = snp_sub;
    //        //                rect.Y = snp.Height - rect.Height;
    //        //            }
    //        //        }
    //        //    }
    //        //    else if (rect.Y + rect.Height == snp.Height)
    //        //    {
    //        //        if (Math.Abs(mouse_up[0] - mouse_down[0]) >= Math.Abs(mouse_up[1] - mouse_down[1]))
    //        //        {
    //        //            if (start_self[1] < offset.size_Layer[1] - 1)
    //        //            {
    //        //                start_sub[1] = start_self[1] + 1;
    //        //                end_sub[1] = end_self[1] + 1;
    //        //                this.puzzle(start_sub, end_sub, true);
    //        //                snp = snp_sub;
    //        //                rect.X = 0;
    //        //            }
    //        //        }
    //        //        else
    //        //        {
    //        //            if (start_self[0] < offset.size_Layer[0] - 1)
    //        //            {
    //        //                start_sub[0] = start_self[0] + 1;
    //        //                end_sub[0] = end_self[0] + 1;
    //        //                this.puzzle(start_sub, end_sub, true);
    //        //                snp = snp_sub;
    //        //                rect.Y = 0;
    //        //            }
    //        //        }
    //        //    }
    //        //    else
    //        //    {
    //        //        if (start_self[1] < offset.size_Layer[1] - 1)
    //        //        {
    //        //            start_sub[1] = start_self[1] + 1;
    //        //            end_sub[1] = end_self[1] + 1;
    //        //            this.puzzle(start_sub, end_sub, true);
    //        //            snp = snp_sub;
    //        //            rect.X = 0;
    //        //        }
    //        //    }
    //        //    start_self[0] = start_sub[0];
    //        //    start_self[1] = start_sub[1];
    //        //    end_self[0] = end_sub[0];
    //        //    end_self[1] = end_sub[1];
    //        //    Console.WriteLine("2");
    //        //}

    //        //else if (rect.Y == 0)
    //        //{
    //        //    if (start_self[0] > 0)
    //        //    {
    //        //        start_sub[0] = start_self[0] - 1;
    //        //        end_sub[0] = end_self[0] - 1;
    //        //        this.puzzle(start_sub, end_sub, true);
    //        //        snp = snp_sub;
    //        //        rect.Y = snp.Height - rect.Height;
    //        //    }
    //        //    start_self[0] = start_sub[0];
    //        //    start_self[1] = start_sub[1];
    //        //    end_self[0] = end_sub[0];
    //        //    end_self[1] = end_sub[1];
    //        //    Console.WriteLine("3");
    //        //}

    //        //else if (rect.Y + rect.Height == snp.Height)
    //        //{
    //        //    if (start_self[0] < offset.size_Layer[0] - 1)
    //        //    {
    //        //        start_sub[0] = start_self[0] + 1;
    //        //        end_sub[0] = end_self[0] + 1;
    //        //        this.puzzle(start_sub, end_sub, true);
    //        //        snp = snp_sub;
    //        //        rect.Y = 0;
    //        //    }
    //        //    start_self[0] = start_sub[0];
    //        //    start_self[1] = start_sub[1];
    //        //    end_self[0] = end_sub[0];
    //        //    end_self[1] = end_sub[1];
    //        //    Console.WriteLine("4");
    //        //}

    //        if (rect_x_zero)
    //        {
    //            if (rect_y_zero)
    //            {
    //                if (Math.Abs(mouse_up[0] - mouse_down[0]) >= Math.Abs(mouse_up[1] - mouse_down[1]))
    //                {
    //                    if (start_self[1] > 0)
    //                    {
    //                        start_sub[1] = start_self[1] - 1;
    //                        end_sub[1] = end_self[1] - 1;
    //                        this.puzzle(start_sub, end_sub, true);
    //                        snp = snp_sub;
    //                        rect.X = snp.Width - rect.Width;
    //                        Console.WriteLine("10");
    //                    }
    //                }
    //                else
    //                {
    //                    if (start_self[0] > 0)
    //                    {
    //                        start_sub[0] = start_self[0] - 1;
    //                        end_sub[0] = end_self[0] - 1;
    //                        this.puzzle(start_sub, end_sub, true);
    //                        snp = snp_sub;
    //                        rect.Y = snp.Height - rect.Height;
    //                        Console.WriteLine("11");
    //                    }
    //                }
    //            }
    //            else if (rect_y_max)
    //            {
    //                if (Math.Abs(mouse_up[0] - mouse_down[0]) >= Math.Abs(mouse_up[1] - mouse_down[1]))
    //                {
    //                    if (start_self[1] > 0)
    //                    {
    //                        start_sub[1] = start_self[1] - 1;
    //                        end_sub[1] = end_self[1] - 1;
    //                        this.puzzle(start_sub, end_sub, true);
    //                        snp = snp_sub;
    //                        rect.X = snp.Width - rect.Width;
    //                        Console.WriteLine("12");
    //                    }
    //                }
    //                else
    //                {
    //                    if (start_self[0] < offset.size_Layer[0] - 1)
    //                    {
    //                        start_sub[0] = start_self[0] + 1;
    //                        end_sub[0] = end_self[0] + 1;
    //                        this.puzzle(start_sub, end_sub, true);
    //                        snp = snp_sub;
    //                        rect.Y = 0;
    //                        Console.WriteLine("13");
    //                    }
    //                }
    //            }
    //            else
    //            {
    //                if (start_self[1] > 0)
    //                {
    //                    start_sub[1] = start_self[1] - 1;
    //                    end_sub[1] = end_self[1] - 1;
    //                    this.puzzle(start_sub, end_sub, true);
    //                    snp = snp_sub;
    //                    rect.X = snp.Width - rect.Width;
    //                    Console.WriteLine("14");
    //                }
    //            }
    //            start_self[0] = start_sub[0];
    //            start_self[1] = start_sub[1];
    //            end_self[0] = end_sub[0];
    //            end_self[1] = end_sub[1];
    //            Console.WriteLine("1");
    //        }

    //        else if (rect_x_max)
    //        {
    //            if (rect_y_zero)
    //            {
    //                if (Math.Abs(mouse_up[0] - mouse_down[0]) >= Math.Abs(mouse_up[1] - mouse_down[1]))
    //                {
    //                    if (start_self[1] < offset.size_Layer[1] - 1)
    //                    {
    //                        start_sub[1] = start_self[1] + 1;
    //                        end_sub[1] = end_self[1] + 1;
    //                        this.puzzle(start_sub, end_sub, true);
    //                        snp = snp_sub;
    //                        rect.X = 0;
    //                    }
    //                }
    //                else
    //                {
    //                    if (start_self[0] > 0)
    //                    {
    //                        start_sub[0] = start_self[0] - 1;
    //                        end_sub[0] = end_self[0] - 1;
    //                        this.puzzle(start_sub, end_sub, true);
    //                        snp = snp_sub;
    //                        rect.Y = snp.Height - rect.Height;
    //                    }
    //                }
    //            }
    //            else if (rect_y_max)
    //            {
    //                if (Math.Abs(mouse_up[0] - mouse_down[0]) >= Math.Abs(mouse_up[1] - mouse_down[1]))
    //                {
    //                    if (start_self[1] < offset.size_Layer[1] - 1)
    //                    {
    //                        start_sub[1] = start_self[1] + 1;
    //                        end_sub[1] = end_self[1] + 1;
    //                        this.puzzle(start_sub, end_sub, true);
    //                        snp = snp_sub;
    //                        rect.X = 0;
    //                    }
    //                }
    //                else
    //                {
    //                    if (start_self[0] < offset.size_Layer[0] - 1)
    //                    {
    //                        start_sub[0] = start_self[0] + 1;
    //                        end_sub[0] = end_self[0] + 1;
    //                        this.puzzle(start_sub, end_sub, true);
    //                        snp = snp_sub;
    //                        rect.Y = 0;
    //                    }
    //                }
    //            }
    //            else
    //            {
    //                if (start_self[1] < offset.size_Layer[1] - 1)
    //                {
    //                    start_sub[1] = start_self[1] + 1;
    //                    end_sub[1] = end_self[1] + 1;
    //                    this.puzzle(start_sub, end_sub, true);
    //                    snp = snp_sub;
    //                    rect.X = 0;
    //                }
    //            }
    //            start_self[0] = start_sub[0];
    //            start_self[1] = start_sub[1];
    //            end_self[0] = end_sub[0];
    //            end_self[1] = end_sub[1];
    //            Console.WriteLine("2");
    //        }

    //        else if (rect_y_zero)
    //        {
    //            if (start_self[0] > 0)
    //            {
    //                start_sub[0] = start_self[0] - 1;
    //                end_sub[0] = end_self[0] - 1;
    //                this.puzzle(start_sub, end_sub, true);
    //                snp = snp_sub;
    //                rect.Y = snp.Height - rect.Height;
    //            }
    //            start_self[0] = start_sub[0];
    //            start_self[1] = start_sub[1];
    //            end_self[0] = end_sub[0];
    //            end_self[1] = end_sub[1];
    //            Console.WriteLine("3");
    //        }

    //        else if (rect_y_max)
    //        {
    //            if (start_self[0] < offset.size_Layer[0] - 1)
    //            {
    //                start_sub[0] = start_self[0] + 1;
    //                end_sub[0] = end_self[0] + 1;
    //                this.puzzle(start_sub, end_sub, true);
    //                snp = snp_sub;
    //                rect.Y = 0;
    //            }
    //            start_self[0] = start_sub[0];
    //            start_self[1] = start_sub[1];
    //            end_self[0] = end_sub[0];
    //            end_self[1] = end_sub[1];
    //            Console.WriteLine("4");
    //        }

    //        if (rect.X < 0)
    //        {
    //            rect.X = 0;
    //        }
    //        if (rect.Y < 0)
    //        {
    //            rect.Y = 0;
    //        }
    //        if (rect.X + rect.Width > snp.Width)
    //        {
    //            rect.X = snp.Width - rect.Width;
    //        }
    //        if (rect.Y + rect.Height > snp.Height)
    //        {
    //            rect.Y = snp.Height - rect.Height;
    //        }

    //        shift_sub = false;
    //        send_sub = false;

    //        return snp.GetSubRect(rect);
    //    }

    //    public void ReceiveEvent(int[] start, int[] end)
    //    {
    //        task =
    //              Task.Run(
    //              () => this.puzzle(start, end, false));
    //    }
    //    public void ReceiveOverPuzzle()
    //    {
    //        int[] rect_los = new int[2];
    //        int[] los_back = new int[2];
    //        rect_los[0] = rect.X;
    //        rect_los[1] = rect.Y;
    //        los_back[0] = (Position[start_back[0]][start_back[1]][0] - Position[start_self[0]][start_self[1]][0]) * (int)(Math.Pow(2, lay - 1)) + pos_self[0];
    //        los_back[1] = (Position[start_back[0]][start_back[1]][1] - Position[start_self[0]][start_self[1]][1]) * (int)(Math.Pow(2, lay - 1)) + pos_self[1];
    //        if (SendRectEvent != null)
    //        {
    //            Console.WriteLine(los_back[0].ToString() + ',' + los_back[1].ToString());
    //            //Console.WriteLine(rect.Location);
    //            SendRectEvent(los_back, rect_los, rect.Width, rect.Height, lay);
    //        }
    //    }

    //    public void ReceiverOverSelf()
    //    {
    //        if (control_back == true)
    //        {
    //            send_back = false;
    //            shift = false;
    //        }
    //    }

    //    public void ReceiveBeforeOverSelf()
    //    {
    //        shift = false;
    //    }

    //    public void ReceiveBackStartSelf()
    //    {
    //        shift = true;
    //        if (rect.Width != 0 && rect.Height != 0)
    //        {
    //            rect.X = rect_start.X;
    //            rect.Y = rect_start.Y;
    //            rect.Width = rect_start.Width;
    //            rect.Height = rect_start.Height;
    //        }
    //        Console.WriteLine(rect.Location);
    //        Console.WriteLine(rect.Size);
    //    }

    //    public int[] Scan(int X, int Y)
    //    {
    //        int[] spot = new int[2] { 0, 0 };
    //        int x, y;

    //        x = X;
    //        y = Y;
    //        for (int i = 0; i < Position.Count; i++)
    //        {
    //            for (int j = 0; j < Position[i].Count; j++)
    //            {
    //                if (i == 0 && j == 0 && ((x >= Position[i][j][0] && x < Position[i][j + 1][0] && y < Position[i][j][1]) || (x <= Position[i][j][0] && y >= Position[i][j][1] && y < Position[i + 1][j][1]) || (x <= Position[i][j][0] && y < Position[i][j][1])))
    //                {
    //                    spot[0] = i;
    //                    spot[1] = j;
    //                    break;
    //                }
    //                else if (i == 0 && y < Position[i][j][1])
    //                {
    //                    if ((j == Position[i].Count - 1 && x >= Position[i][j][0]) || (x >= Position[i][j][0] && x < Position[i][j + 1][0]))
    //                    {
    //                        spot[0] = i;
    //                        spot[1] = j;
    //                        break;
    //                    }
    //                }
    //                else if (j == 0 && x <= Position[i][j][0])
    //                {
    //                    if ((i == Position.Count - 1 && y >= Position[i][j][1]) || (y >= Position[i][j][1] && y < Position[i + 1][j][1]))
    //                    {
    //                        spot[0] = i;
    //                        spot[1] = j;
    //                        break;
    //                    }

    //                }
    //                else if ((j == Position[i].Count - 1 && x >= Position[i][j][0]) || (x >= Position[i][j][0] && x < Position[i][j + 1][0]))
    //                {
    //                    if ((i == Position.Count - 1 && y >= Position[i][j][1]) || (y >= Position[i][j][1] && y < Position[i + 1][j][1]))
    //                    {
    //                        spot[0] = i;
    //                        spot[1] = j;
    //                        break;
    //                    }
    //                }
    //            }
    //        }
    //        return spot;
    //    }

    //    public void puzzle(int[] start, int[] end, bool isSub)
    //    {
    //        int multi = (int)(Math.Pow(2, lay - 1));
    //        int size = 256 * multi;


    //        int max_xz = 0, max_xf = 0, max_x = 0;
    //        int max_yz = 0, max_yf = 0, max_y = 0;

    //        int init_x = 0, init_y = 0;
    //        int move_x = 0, move_y = 0;

    //        max_xf = Position[start[0]][start[1]][1];
    //        max_xz = Position[start[0]][start[1]][1];

    //        Image<Gray, byte> snp_512 = null;

    //        var files = Directory.GetFiles(path);


    //        if (lay == 0)
    //        {
    //            Array.Sort(files, delegate (string s1, string s2)
    //            {
    //                return
    //                ((int.Parse(s1.Split('_')[1]) * 10000 + int.Parse(s1.Split('_')[2]) * 100 + int.Parse(s1.Split('_')[3])).
    //                CompareTo((int.Parse(s2.Split('_')[1]) * 10000 + int.Parse(s2.Split('_')[2]) * 100 + int.Parse(s2.Split('_')[3])))
    //                );
    //            });
    //            snp_512 = new Image<Gray, byte>(files[start[0] * offset.size_Layer[1] + start[1]]);
    //        }
    //        else
    //        {
    //            Array.Sort(files, delegate (string s1, string s2)
    //            {
    //                return
    //                ((int.Parse(s1.Split('_')[2]) * 10000 + int.Parse(s1.Split('_')[3]) * 100 + int.Parse(s1.Split('_')[4])).
    //                CompareTo((int.Parse(s2.Split('_')[2]) * 10000 + int.Parse(s2.Split('_')[3]) * 100 + int.Parse(s2.Split('_')[4])))
    //                );
    //            });
    //            for (int i = start[1]; i <= end[1]; i++)
    //            {
    //                if (max_xf > Position[start[0]][i][1])
    //                {
    //                    max_xf = Position[start[0]][i][1];
    //                }
    //                if (max_xz < Position[start[0]][i][1])
    //                {
    //                    max_xz = Position[start[0]][i][1];
    //                }
    //            }
    //            max_yf = Position[start[0]][start[1]][0];
    //            max_yz = Position[start[0]][start[1]][0];
    //            for (int i = start[0]; i <= end[0]; i++)
    //            {
    //                if (max_yf > Position[i][start[1]][0])
    //                {
    //                    max_yf = Position[i][start[1]][0];
    //                }
    //                if (max_yz < Position[i][start[1]][0])
    //                {
    //                    max_yz = Position[i][start[1]][0];
    //                }
    //            }
    //            max_x = max_xz - max_xf;
    //            max_y = max_yz - max_yf;

    //            snp_512 = new Image<Gray, byte>(size * (end[1] - start[1] + 2) + max_y * multi, size * (end[0] - start[0] + 2) + max_x * multi);
    //            Image<Gray, byte> ex1 = null;

    //            init_x = (size / 2) + (Position[start[0]][start[1]][0] - max_yf) * multi;
    //            init_y = (size / 2) + (Position[start[0]][start[1]][1] - max_xf) * multi;

    //            move_x = (Position[start[0]][start[1]][0] * multi) - init_x;
    //            move_y = (Position[start[0]][start[1]][1] * multi) - init_y;

    //            Console.WriteLine(start[0].ToString() + ",," + start[1].ToString());
    //            Console.WriteLine(end[0].ToString() + ",," + end[1].ToString());
    //            for (int i = start[0]; i <= end[0]; i++)
    //            {
    //                for (int j = start[1]; j <= end[1]; j++)
    //                {
    //                    //new System.Threading.Thread(delegate ()
    //                    //{
    //                    //ex1 = new Image<Gray, byte>(files[i * Form1.offset.size_Layer[1] + j]);
    //                    //ex1 = ex1.Resize(size, size, Emgu.CV.CvEnum.Inter.Linear);
    //                    ex1 = new Image<Gray, byte>(files[i * offset.size_Layer[1] + j]);
    //                    form.copy(Position[i][j][1] * multi - move_y, Position[i][j][0] * multi - move_x, snp_512, ex1);
    //                    Console.WriteLine(i.ToString() + "|" + j.ToString());
    //                    //}).Start();
    //                }
    //            }
    //        }
    //        Console.WriteLine("puzzle end");
    //        snp_512.Save("C:\\Users\\user\\Documents\\result\\snp1_2_3_4.jpg");
    //        if (!isSub)
    //        {
    //            snp = snp_512;
    //            if (lay == 0)
    //            {
    //                pos_self[0] = 0;
    //                pos_self[1] = 0;
    //            }
    //            else
    //            {
    //                pos_self[0] = Position[start[0]][start[1]][0] * multi - move_x;
    //                pos_self[1] = Position[start[0]][start[1]][1] * multi - move_y;
    //            }
    //            start_self[0] = start[0];
    //            start_self[1] = start[1];
    //            end_self[0] = end[0];
    //            end_self[1] = end[1];

    //            if (OverPuzzleEvent != null)
    //            {
    //                OverPuzzleEvent();
    //            }
    //        }
    //        else
    //        {
    //            if (lay == 0)
    //            {
    //                snp_sub = snp_512;
    //                pos_sub[0] = 0;
    //                pos_sub[1] = 0;
    //            }
    //            else
    //            {
    //                snp_sub = snp_512;
    //                pos_sub[0] = Position[start[0]][start[1]][0] * multi - move_x;
    //                pos_sub[1] = Position[start[0]][start[1]][1] * multi - move_y;
    //                shift_sub = true;
    //            }
    //        }
    //        //Form1.start_512 = start;
    //        //Form1.end_512 = end;
    //        //Form1.sendtask_512 = false;
    //        //if (Form1.control_512)
    //        //{
    //        //    Form1.shift_512 = true;
    //        //}
    //    }

    //    public void Draw_rect(int[] los_before, int[] rect_los, int rect_wid, int rect_hei, int img_size)
    //    {
    //        int[] mid = new int[2];
    //        if (lay == 0)
    //        {
    //            mid[0] = (int)((rect_los[0] + rect_wid / 2 - los_before[0]) * (snp.Width / (Math.Pow(2, img_size - 1) * 256)));
    //            mid[1] = (int)((rect_los[1] + rect_hei / 2 - los_before[1]) * (snp.Height / (Math.Pow(2, img_size - 1) * 256)));
    //            if (((mid[0] >= snp.Width * 0.3) && (mid[0] <= snp.Width * 0.7)) && ((mid[1] >= snp.Height * 0.3) && (mid[1] <= snp.Height * 0.7)))
    //            {
    //                rect.Width = (int)(snp.Width * 0.5);
    //                rect.Height = rect.Width * rect_hei / rect_wid;
    //                rect.X = mid[0] - rect.Width / 2;
    //                rect.Y = mid[1] - rect.Height / 2;
    //            }
    //            else
    //            {
    //                rect.X = (int)((rect_los[0] - los_before[0]) * (snp.Width / (Math.Pow(2, img_size - 1) * 256)) + pos_self[0]);
    //                rect.Y = (int)((rect_los[1] - los_before[1]) * (snp.Height / (Math.Pow(2, img_size - 1) * 256)) + pos_self[1]);
    //                if (rect.X < 0)
    //                {
    //                    rect.X = 0;
    //                }
    //                if (rect.Y < 0)
    //                {
    //                    rect.Y = 0;
    //                }
    //                if (rect.X + rect.Width > snp.Width)
    //                {
    //                    rect.X = snp.Width - rect.Width;
    //                }
    //                if (rect.Y + rect.Height > snp.Height)
    //                {
    //                    rect.Y = snp.Height - rect.Height;
    //                }
    //            }
    //        }
    //        else
    //        {
    //            rect.X = ((rect_los[0] - los_before[0]) * (lay - img_size) * 2) + pos_self[0];
    //            rect.Y = ((rect_los[1] - los_before[1]) * (lay - img_size) * 2) + pos_self[1];
    //            rect.Width = rect_wid * (lay - img_size) * 2;
    //            rect.Height = rect_hei * (lay - img_size) * 2;
    //        }
    //        widr = snp.Width;
    //        heir = snp.Width * rect.Height / rect.Width;
    //        level = (double)rect.Width / widr;
    //        //Console.WriteLine(rect.Size);
    //        shift = true;
    //        if (OverSelfEvent != null)
    //        {
    //            OverSelfEvent();
    //        }
    //    }
    //}
}
